package main

import (
	"fmt"
	"github.com/spf13/viper"
	"github.com/xuri/excelize/v2"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

// todo 生成加班日期目录，用于自己去整理证据
var baseDir = "C:\\Users\\Administrator\\Desktop\\记录\\证据\\日期\\"

// todo 工作日志路径
var logpath = "C:\\Users\\Administrator\\Desktop\\记录\\证据\\文档\\工作日志.xlsx"

var hourMoney []string

var tiaoxiutianshu []string

/**
 *	todo 获取日期对应时薪
 */
//func getHourMoney(date string) float64 {
//	//这里瞎写的月工资1万，你们写自己的
//	hourmoney1 := 16000 * 0.8 / 21.75 / 8
//	hourmoney2 := 16000 / 21.75 / 8
//	hourmoney3 := 16000 / 21.75 / 8
//	hourmoney4 := 16000 / 21.75 / 8
//	if date <= "2020-08-18" {
//		//0天调休
//		return hourmoney1
//	}
//	if date < "2022-05-01" {
//		//4天调休
//		return hourmoney2
//	}
//	if date < "2023-05-01" {
//		//2天调休
//		return hourmoney3
//	}
//	//8.5天调休
//	return hourmoney4
//}

func getHourMoney(date string) float64 {
	for _, m := range hourMoney {
		slices := strings.Split(m, ",")
		d := slices[0]
		if date <= d {
			money, _ := strconv.ParseFloat(strings.TrimSpace(slices[1]), 64)
			return money / 21.75 / 8
		}
	}
	panic("配置错误")
}

func getTiaoxiutianshu() (float64, float64) {
	var tiaoxiumoney float64
	var ts float64
	for _, m := range tiaoxiutianshu {
		slices := strings.Split(m, ",")
		d := slices[0]
		days := slices[1]
		dayss, _ := strconv.ParseFloat(strings.TrimSpace(days), 64)
		tiaoxiumoney += getHourMoney(d) * 8 * dayss * 2
		ts += dayss
	}
	return tiaoxiumoney, ts
}

func main() {
	viper.SetConfigName("config")
	viper.SetConfigType("toml")
	viper.AddConfigPath(".")

	err := viper.ReadInConfig()
	if err != nil {
		panic(fmt.Errorf("fatal error config file: %s\n", err))
	}

	// 读取配置项
	baseDir = viper.GetString("baseDir")
	logpath = viper.GetString("logpath")
	hourMoney = viper.GetStringSlice("hourMoney")
	triplePayHolidays = viper.GetStringSlice("triplePayHolidays")
	doublePayHolidays = viper.GetStringSlice("doublePayHolidays")
	workingAdjustmentDays = viper.GetStringSlice("workingAdjustmentDays")
	tiaoxiutianshu = viper.GetStringSlice("tiaoxiutianshu")

	total := calmoney(logpath)
	fmt.Println("应发加班费总计", total)

	//todo 已给3倍
	//yfjbf := 4346.0
	//fmt.Println("已给法定节假日的3倍工资约", yfjbf, "元，具体需公司提供")

	//有些休息日、周末的加班给调休了，所以要减去调休日期多算的加班费
	//txmoney := getHourMoney("2022-04-29")*8*4*2 + getHourMoney("2023-04-29")*8*2*2 + getHourMoney("2024-07-14")*8*8.5*2
	txmoney, ts := getTiaoxiutianshu()
	fmt.Println("已给调休", ts, "天，涉及金额", txmoney, "元，需减去")

	fmt.Printf("应补发加班费总计,%f元\n", total-txmoney)
	fmt.Println("其中周三加班费", zhousanmoney, "元")
	fmt.Println("其中法定3倍加班费", fd3bmoney, "元")
	fmt.Println("其中法定2倍加班费", fd2bmoney, "元")
	fmt.Println("其中周末加班费", zhoumomoney, "元")
	fmt.Println("其中非周三工作日加班费", qtgzrmoney, "元")

	fmt.Println("已给法定节假日的3倍工资请自行减去")

	fmt.Scanln()
}

var zhousanmoney float64
var fd3bmoney float64
var fd2bmoney float64

var zhoumomoney float64
var qtgzrmoney float64

type workday struct {
	date     string
	worktime float64
}

func calmoney(excel string) float64 {
	fmt.Println("读取每日工作时长")
	f, err := excelize.OpenFile(excel)
	if err != nil {
		fmt.Println(err)
		return 0
	}
	rows, err := f.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return 0
	}
	dateTimeMap := make(map[string]string)
	for _, row := range rows {
		if row[1] == "日志日期" {
			continue
		}
		date := row[1]
		time := row[4]
		if v, ok := dateTimeMap[date]; ok {
			t1, _ := strconv.ParseFloat(v, 64)
			t2, _ := strconv.ParseFloat(time, 64)
			t := t1 + t2
			dateTimeMap[date] = strconv.FormatFloat(t, 'f', 2, 64)
		} else {
			dateTimeMap[date] = time
		}
	}

	var worddays []workday

	for k, v := range dateTimeMap {
		f, _ := strconv.ParseFloat(v, 64)
		worddays = append(worddays, workday{date: k, worktime: f})
	}

	sort.Slice(worddays, func(i, j int) bool {
		return worddays[i].date < worddays[j].date
	})

	total := 0.0

	for _, v := range worddays {
		m := cal(v.date, v.worktime)
		total += m
	}
	return total
}

func checkDirectoryExists(dirPath string) bool {
	_, err := os.Stat(dirPath)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	fmt.Println("Error occurred while checking directory:", err)
	return false
}

func mkdirWhenNotExists(dirPath string) {
	targetDir := baseDir + dirPath
	if !checkDirectoryExists(targetDir) {
		os.Mkdir(targetDir, 755)
	}
}

func cal(date string, worktimeF float64) float64 {
	hourmoney := getHourMoney(date)
	if contains(triplePayHolidays, date) {
		m := 3 * hourmoney * worktimeF
		log := fmt.Sprintf("%s是法定节假日,工作时长为%f, 3 倍工资：%f", date, worktimeF, m)
		fmt.Println(log)
		fd3bmoney += m
		mkdirWhenNotExists(log)
		return m
	} else if contains(doublePayHolidays, date) {
		m := 2 * hourmoney * worktimeF
		log := fmt.Sprintf("%s是法定节假日休息日,工作时长为%f, 2 倍工资：%f", date, worktimeF, m)
		fmt.Println(log)
		fd2bmoney += m
		mkdirWhenNotExists(log)
		return m
	} else if contains(workingAdjustmentDays, date) {
		if worktimeF > 8 {
			m := 1.5 * hourmoney * (worktimeF - 8)
			log := fmt.Sprintf("%s是法定节假日调休日,工作时长为%f, 加班时长为%f,1.5 倍工资：%f", date, worktimeF, worktimeF-8, m)
			fmt.Println(log)
			qtgzrmoney += m
			mkdirWhenNotExists(log)
			return m
		}
		return 0
	} else if isWeekend(date) {
		m := 2 * hourmoney * worktimeF
		log := fmt.Sprintf("%s是周末,工作时长为%f, 加班时长为%f,2 倍工资：%f", date, worktimeF, worktimeF-8, m)
		fmt.Println(log)
		mkdirWhenNotExists(log)
		zhoumomoney += m
		return m
	} else if isZhouSan(date) {
		if worktimeF < 11 {
			worktimeF = 11
		}
		m := 1.5 * hourmoney * (worktimeF - 8)
		log := fmt.Sprintf("%s是周三工作日,为固定加班日，至少到9点,工作时长为%f, 加班时长为%f,1.5 倍工资：%f", date, worktimeF, worktimeF-8, m)
		fmt.Println(log)
		mkdirWhenNotExists(log)
		zhousanmoney += m
		return m
	} else {
		if worktimeF > 8 {
			m := 1.5 * hourmoney * (worktimeF - 8)
			log := fmt.Sprintf("%s是工作日,工作时长为%f, 加班时长为%f,1.5 倍工资：%f", date, worktimeF, worktimeF-8, m)
			fmt.Println(log)
			mkdirWhenNotExists(log)
			qtgzrmoney += m
			return m
		}
		return 0
	}
}

func contains(dates []string, target string) bool {
	for _, date := range dates {
		if date == target {
			return true
		}
	}
	return false
}

func isWeekend(dateStr string) bool {
	date, err := stringToTime(dateStr)
	if err != nil {
		fmt.Println(err)
		return false
	}
	dayOfWeek := date.Weekday()
	return dayOfWeek == time.Saturday || dayOfWeek == time.Sunday
}

func isZhouSan(dateStr string) bool {
	date, err := stringToTime(dateStr)
	if err != nil {
		fmt.Println(err)
		return false
	}
	dayOfWeek := date.Weekday()
	return dayOfWeek == time.Wednesday
}

func stringToTime(dateStr string) (time.Time, error) {
	layout := "2006-01-02"
	t, err := time.Parse(layout, dateStr)
	return t, err
}

// 法定节假日 3 倍工资的日期（yyyy-MM-dd 格式）
var triplePayHolidays = []string{
	"2020-01-01",
	"2020-01-25",
	"2020-01-26",
	"2020-01-27",
	"2020-01-28",
	"2020-01-29",
	"2020-01-30",
	"2020-04-04",
	"2020-05-01",
	"2020-06-25",
	"2020-10-01",
	"2020-10-02",
	"2020-10-03",
	"2020-10-04",
	"2020-10-05",
	"2020-10-06",
	"2020-10-07",

	"2021-01-01",
	"2021-02-12",
	"2021-02-13",
	"2021-02-14",
	"2021-02-15",
	"2021-02-16",
	"2021-02-17",
	"2021-04-04",
	"2021-05-01",
	"2021-06-14",
	"2021-09-21",
	"2021-10-01",
	"2021-10-02",
	"2021-10-03",

	"2022-01-01",
	"2022-01-31",
	"2022-02-01",
	"2022-02-02",
	"2022-02-03",
	"2022-04-05",
	"2022-05-01",
	"2022-06-03",
	"2022-09-10",
	"2022-10-01",
	"2022-10-02",
	"2022-10-03",

	"2023-01-01",
	"2023-01-22",
	"2023-01-23",
	"2023-01-24",
	"2023-04-05",
	"2023-05-01",
	"2023-06-22",
	"2023-09-29",
	"2023-10-01",
	"2023-10-02",
	"2023-10-03",

	"2024-01-01",
	"2024-02-10",
	"2024-02-11",
	"2024-02-12",
	"2024-04-04",
	"2024-05-01",
	"2024-06-10",
}

// 法定节假日 2 倍工资的日期（yyyy-MM-dd 格式）
var doublePayHolidays = []string{
	"2020-01-24",
	"2020-01-31",
	"2020-04-06",
	"2020-05-04",
	"2020-05-05",
	"2020-06-26",
	"2020-06-27",
	"2020-09-27",
	"2020-10-08",
	"2020-10-09",

	"2021-02-11",
	"2021-02-18",
	"2021-02-20",
	"2021-04-03",
	"2021-04-05",
	"2021-04-25",
	"2021-05-02",
	"2021-05-03",
	"2021-05-04",
	"2021-05-08",
	"2021-06-12",
	"2021-06-13",
	"2021-09-18",
	"2021-09-19",
	"2021-09-20",
	"2021-09-26",
	"2021-10-04",
	"2021-10-05",
	"2021-10-06",
	"2021-10-07",

	"2022-01-30",
	"2022-02-04",
	"2022-02-05",
	"2022-02-06",
	"2022-04-03",
	"2022-04-06",
	"2022-04-30",
	"2022-05-02",
	"2022-05-03",
	"2022-05-04",
	"2022-06-04",
	"2022-09-11",
	"2022-09-12",

	"2023-01-21",
	"2023-01-25",
	"2023-01-26",
	"2023-01-27",
	"2023-04-02",
	"2023-04-09",
	"2023-05-07",
	"2023-06-23",
	"2023-06-24",
	"2023-09-30",

	"2024-02-09",
	"2024-02-13",
	"2024-04-05",
	"2024-06-09",
}

// 调休日视为工作日（yyyy-MM-dd 格式）
var workingAdjustmentDays = []string{
	// 请根据实际调休情况添加日期
	"2020-01-19",
	"2020-02-01",
	"2020-04-26",
	"2020-05-09",
	"2020-06-28",
	"2020-09-27",
	"2020-10-10",

	"2021-02-07",
	"2021-02-20",
	"2021-04-25",
	"2021-05-08",
	"2021-09-18",
	"2021-09-26",
	"2021-10-09",

	"2022-01-29",
	"2022-01-30",
	"2022-04-02",
	"2022-04-24",
	"2022-05-07",
	"2022-10-08",
	"2022-10-09",

	"2023-01-28",
	"2023-01-29",
	"2023-04-23",
	"2023-05-06",
	"2023-06-25",
	"2023-10-07",
	"2023-10-08",

	"2024-02-04",
	"2024-02-18",
	"2024-04-07",
	"2024-04-28",
	"2024-05-11",
	"2024-09-14",
	"2024-09-29",
	"2024-10-12",
}
